#include "StdAfx.h"

#include "Monster.h"
#include "ObjPhysicsReader.h"
#include "D3DUtil.h"
#include "Level.h"
#include "GraphCamera.h"
#include "CookingStream.h"
#include "DX10ObjMesh.h"
#include "meshtoobjwriter.h"
#include "ObjMesh.h"
#include "ObjReader.h"
#include "Character.h"
#include "BinAnimationReader.h"

Monster::Monster(Level* level, tstring filename, tstring physicsFileName, float3 loc, float3 rot, PhysX *pPhysX, D3DApp *app, Character* pPlayer) : 
	LevelElement(), 
	m_pLevel(level),
	m_filename(filename), 
	m_physicsFileName(physicsFileName), 
	m_Pos(loc), 
	m_Rot(rot),
	m_pPhysX(pPhysX),
	m_app(app),
	m_pActor(0),
	m_pPlayer(pPlayer)
{
	
}

Monster::~Monster(void)
{
	
}

void Monster::Initialize(ContentManager *pContentManager)
{	
	m_BoundingSphereRadius = 4;
	BuildPhysicsMesh();
	BuildDrawMesh();

	m_pDrawMesh->SetParent(m_pLevel);
	m_pDrawMesh->Initialize(pContentManager);
	m_pLevel->AddChild(m_pDrawMesh);

	LoadAnimation();
	Rotate(D3DXVECTOR3(m_Rot.x,m_Rot.y,m_Rot.z));
	Translate(D3DXVECTOR3(m_Pos.x,m_Pos.y,m_Pos.z));
	
	SetPhysXGlobalPose();

}

bool Monster::BuildPhysicsMesh()
{
	if(m_pActor) m_pPhysX->GetScene()->releaseActor(*m_pActor);
	string str = string(m_physicsFileName.begin(), m_physicsFileName.end());
	NxTriangleMesh *pTriangleMesh = m_pPhysX->GetSDK()->createTriangleMesh(UserStream(str.c_str(),true));

	//create triangle mesh instance
	NxTriangleMeshShapeDesc TriangleMeshShapeDesc;

	//enable triggering
	TriangleMeshShapeDesc.shapeFlags |= NX_TRIGGER_ENABLE;
	//calc mass, using AABB volume
	TriangleMeshShapeDesc.mass = 200;
	//set meshdata
	TriangleMeshShapeDesc.meshData  = pTriangleMesh;

	NxActorDesc ActorDesc;
	ActorDesc.shapes.push_back(&TriangleMeshShapeDesc);
	ActorDesc.globalPose.t = NxVec3( 0,0,0 );
	ActorDesc.body=0;

	m_pActor = m_pPhysX->GetScene()->createActor(ActorDesc);
	m_pActor->userData = this;

	return m_pActor != 0;
}

void Monster::BuildDrawMesh()
{
	IniFile* config = new IniFile();
	config->SetValue(_T("Export"),_T("baseDir"),_T("."));
	config->SetValue(_T("Export"),_T("meshDir"),_T(""));
	config->SetValue(_T("Export"),_T("textureDir"),_T(""));
	config->SetValue(_T("Export"),_T("skeletonDir"),_T(""));

	ObjReader reader(config,m_filename);
	if ( reader.Read() )
	{
		MeshList* list = new MeshList();
		reader.CopyIntoMeshList(list);
		vector<ObjMesh*>::const_iterator it;
		for (it=list->begin(); it!= list->end(); it++)
		{
			ObjMesh* mesh = *it;
			// standaard shader meegeven
			DX10ObjMesh* dx10Mesh = m_app->Compile(mesh,_T("NormalMap.fx"), _T("checkertech"));
			if ( dx10Mesh != 0 )
			{
				//m_pDrawMesh->SetName(_T("monster"));
				m_pDrawMesh = dx10Mesh;
				
			}
		}
	}
}

void Monster::LoadAnimation(void)
{
	BinAnimationReader bar (L"Models/Monsters/idle.ab");
	if ( bar.Read() )
	{
		Animation* animation = bar.GetAnimation();
		// pas op , GetChildByName moet je nog zelf implementeren.
		DX10ObjMesh* monster = static_cast<DX10ObjMesh*>(m_pDrawMesh);
		monster->AddAnimation(animation);
		monster->ActivateAnimation(L"idle");
	}
}

void Monster::SetPhysXGlobalPose()
{
	SetPhysXGlobalPose(m_World);
}

void Monster::SetPhysXGlobalPose(const D3DXMATRIX& World)
{
	NxMat34 mat;
	mat.setColumnMajor44(World);
	if(m_pActor !=0) m_pActor->setGlobalPose(mat);
}

void Monster::Tick(const InputState & refInputState)
{
	m_pDrawMesh->ResetWorldMatrix();
	m_pDrawMesh->Scale(D3DXVECTOR3(0.015f,0.015f,0.015f));
	m_pDrawMesh->Rotate(D3DXVECTOR3(m_Rot.x,m_Rot.y,m_Rot.z));
	m_pDrawMesh->Translate(D3DXVECTOR3(m_Pos.x,m_Pos.y,m_Pos.z));

	//D3DXVECTOR3 walkDir = m_pPlayer->GetPosition() - D3DXVECTOR3(m_Pos.x, m_Pos.y, m_Pos.z);
	//D3DXVec3Normalize(&walkDir, &walkDir);
	//walkDir*=0.005f;
	//m_Pos.x += walkDir.x;
	//m_Pos.y += walkDir.y;
	//m_Pos.z += walkDir.z;

	//Translate(walkDir);

	if ( m_pActor != 0 )
	{
		m_pActor->getGlobalPose().getColumnMajor44((NxF32*)&m_World.m);
	}
	if(m_pDrawMesh != 0) m_pDrawMesh->Tick(refInputState);
	
}

void Monster::Draw(const RenderContext* pRenderContext)
{
	if(m_pDrawMesh != 0 && m_bEnableDraw) m_pDrawMesh->Draw(pRenderContext);
}

void Monster::Draw(const RenderContext* pRenderContext, ID3D10ShaderResourceView* shadowdepthmap)
{
	if(m_bEnableDraw)
	{
		float temp = 1.0f;
	} else {
		float lol = 2.0f;
	}
        if(m_pDrawMesh != 0 && m_bEnableDraw)
		{
			m_pDrawMesh->Draw(pRenderContext);
		}
}


void Monster::Translate(const D3DXVECTOR3 pos){
	m_pDrawMesh->Translate(pos);
	LevelElement::Translate(pos);
	SetPhysXGlobalPose(m_World);
}

void Monster::Rotate(const D3DXVECTOR3 rot){
	m_pDrawMesh->Rotate(rot);
	LevelElement::Rotate(rot);
	SetPhysXGlobalPose(m_World);
}